package com.spzx.cart.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.ICartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.vo.SkuPrice;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CartServiceImpl implements ICartService {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RemoteProductService remoteProductService;

    @Override
    public void addToCart(Long skuId, Integer num) {
        //1.构建购物车的key
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        String hashKey = String.valueOf(skuId); //小key


        //2.判断商品是否添加过购物车
        BoundHashOperations<String, String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        int threshold = 99; //阈值
        if (boundHashOperations.hasKey(hashKey)) { //添加过
            CartInfo cartInfo = boundHashOperations.get(hashKey);
            int total = cartInfo.getSkuNum() + num;
            cartInfo.setSkuNum(total > threshold ? threshold : total);
            cartInfo.setUpdateTime(new Date());
            boundHashOperations.put(hashKey, cartInfo);
        } else { //首次添加
            Long size = boundHashOperations.size();
            if (++size > 50) {
                throw new ServiceException("商品不能超过50件");
            }

            CartInfo cartInfo = new CartInfo();
            cartInfo.setCreateTime(new Date()); // 使用时间，回显购物车商品倒序排序。
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(skuId);

            R<ProductSku> productSkuResult = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if (R.FAIL == productSkuResult.getCode()) { //状态码 500 说明远程调用降级处理
                throw new ServiceException(productSkuResult.getMsg()); //交给统一异常处理器处理
            }
            ProductSku productSku = productSkuResult.getData();
            cartInfo.setCartPrice(productSku.getSalePrice()); //购物车价格，当时添加购物车时的商品价格
            cartInfo.setSkuPrice(productSku.getSalePrice()); //可能变化的。数据库商品价格变动，购物车显示时回显最新价格。

            cartInfo.setSkuNum(num);
            cartInfo.setThumbImg(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setIsChecked(1);

            boundHashOperations.put(hashKey, cartInfo);
        }

    }

    private String getCartKey(Long userId) {
        String cartKey = "user:cart:" + userId; //大key
        return cartKey;
    }


    @Override
    public List<CartInfo> getCartList() {
        //1.构建购物车的key
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> values = boundHashOperations.values();

        if(CollectionUtils.isEmpty(values)){
            return new ArrayList<>();
        }
        //2.需要更加创建时间倒序排序
        List<CartInfo> sortedValues = values.stream().sorted((o1,o2)->o2.getCreateTime().compareTo(o1.getCreateTime())).toList();

        //3.回显数据库商品最新价格，页面给与用户提示：价格变动
        // select * from product_sku where id in (1,2,3,4,5);
        List<Long> skuIdList = sortedValues.stream().map(CartInfo::getSkuId).toList();
        R<List<SkuPrice>> skuPriceListResult = remoteProductService.getSkuPriceList(skuIdList,SecurityConstants.INNER);

        if(R.FAIL ==  skuPriceListResult.getCode()){
            throw new ServiceException(skuPriceListResult.getMsg());
        }
        //list<SkuPrice> 转 map<Integer,BigDecimal>
        List<SkuPrice> skuPriceList = skuPriceListResult.getData();
        Map<Long, BigDecimal> skuIdToSalePriceMap = skuPriceList.stream()
                .collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));

        for (CartInfo cartInfo : sortedValues) {
            Long skuId = cartInfo.getSkuId();
            BigDecimal salePrice = skuIdToSalePriceMap.get(skuId);
            cartInfo.setSkuPrice(salePrice);
        }

        return sortedValues;
    }


    @Override
    public void deleteCart(Long skuId) {
        //1.构建购物车的key
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        String hashKey = String.valueOf(skuId); //小key

        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        if(boundHashOperations.hasKey(hashKey)){
            boundHashOperations.delete(hashKey);
        }

    }


    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        //1.构建购物车的key
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        String hashKey = String.valueOf(skuId); //小key

        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);

        if(boundHashOperations.hasKey(hashKey)){
            CartInfo cartInfo = boundHashOperations.get(hashKey);
            cartInfo.setIsChecked(isChecked);
            boundHashOperations.put(hashKey,cartInfo);
        }
    }


    @Override
    public void allCheckCart(Integer isChecked) {
        //1.构建购物车的key
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> values = boundHashOperations.values();
        if(!CollectionUtils.isEmpty(values)){
            for (CartInfo cartInfo : values) {
                cartInfo.setIsChecked(isChecked);
                boundHashOperations.put(cartInfo.getSkuId().toString(),cartInfo);
            }
        }
    }


    @Override
    public void clearCart() {
        //1.构建购物车的key
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        redisTemplate.delete(cartKey);
    }

    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        List<CartInfo> cartInfoCheckedList = new ArrayList<>();

        //1.构建购物车的key
        String cartKey = getCartKey(userId);
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> values = boundHashOperations.values();
        if(!CollectionUtils.isEmpty(values)){
            for (CartInfo cartInfo : values) {
                if(cartInfo.getIsChecked() == 1){
                    cartInfoCheckedList.add(cartInfo);
                }
            }
        }
        return cartInfoCheckedList;
    }

/*    @Override
    public Boolean updateCartPrice(Long userId) {
        List<CartInfo> cartInfoCheckedList = new ArrayList<>();

        //1.构建购物车的key
        String cartKey = getCartKey(userId);
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> values = boundHashOperations.values();
        if(!CollectionUtils.isEmpty(values)){
            for (CartInfo cartInfo : values) {
                if(cartInfo.getIsChecked() == 1){
                    R<SkuPrice> skuPriceResult = remoteProductService.getSkuPrice(cartInfo.getSkuId(), SecurityConstants.INNER);
                    SkuPrice skuPrice = skuPriceResult.getData();

                    cartInfo.setCartPrice(skuPrice.getSalePrice());
                    cartInfo.setSkuPrice(skuPrice.getSalePrice());

                    boundHashOperations.put(cartInfo.getSkuId().toString(),cartInfo);
                }
            }
        }

        return true;
    }*/


    @Override
    public Boolean updateCartPrice(Long userId) {

        //1.构建购物车的key
        String cartKey = getCartKey(userId);
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> values = boundHashOperations.values();

        //2.批量获取商品最新价格
        List<Long> skuIdList = values.stream().map(CartInfo::getSkuId).toList();
        R<List<SkuPrice>> skuPriceListResult = remoteProductService.getSkuPriceList(skuIdList, SecurityConstants.INNER);
        if(skuPriceListResult.getCode() == R.FAIL){
            throw new ServiceException(skuPriceListResult.getMsg());
        }
        List<SkuPrice> skuPriceList = skuPriceListResult.getData();

        // List<SkuPrice>  转   Map<Integer,BigDecimal>
        Map<Long, BigDecimal> skuIdToSkuPriceMap = skuPriceList.stream()
                .collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));

        //更新购物车打钩商品价格
        for (CartInfo cartInfo : values) {
            if(cartInfo.getIsChecked() == 1){
                cartInfo.setCartPrice(skuIdToSkuPriceMap.get(cartInfo.getSkuId()));
                cartInfo.setSkuPrice(skuIdToSkuPriceMap.get(cartInfo.getSkuId()));

                boundHashOperations.put(cartInfo.getSkuId().toString(),cartInfo);
            }
        }

        return true;
    }


    @Override
    public Boolean deleteCartCheckedList(Long userId) {
        //1.构建购物车的key
        String cartKey = getCartKey(userId);
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> values = boundHashOperations.values();
        for (CartInfo cartInfo : values) {
            if(cartInfo.getIsChecked() == 1){
                boundHashOperations.delete(cartInfo.getSkuId().toString());
            }
        }

        return true;
    }
}